/*
*  Copyright (C) 2009  Peter Kist & Jan Ripke
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <string>
#include <sstream>

#include <iostream>
#include <noise/noise.h>
#include "noiseutils.h"

#include <octree/octree.h>

#include <boost/random/uniform_real.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>


using namespace noise;

#if _WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT nCmdShow)
#else
int main(int argc, char **argv)
#endif
{
    Octree<int> ot(131072);

    std::ostringstream oss;
    oss << "abc";
    //std::string ossstr ((oss << "abc").str());
    //std::string str ((std::ostringstream() << "hello").str());

    boost::mt19937 rng(43);
    boost::uniform_real<double>  six(1.0,6.0);

    for(int i = 0; i < 10; ++i) {
        float randomNumber = six(rng);
        std::cout << randomNumber << std::endl;
    } 

    float fMass = 1.9891e30;
    double dMass = 1.9891e30;

    std::cout << "\nDisplayed in scientific format:" 
        << std::endl << std::scientific << fMass << '\t' << dMass << std::endl;

    module::Perlin galaxyNoise;
    //for (int z = 
    //galaxyNoise.GetValue(

    ot.set (100,100,100,10);
    ot.set (120,120,120,12);

    module::Perlin myModule;
    myModule.SetSeed(3784377);
    myModule.SetOctaveCount(6);
    //myModule.SetPersistence(0.6);
    //myModule.SetLacunarity(2.5);
    myModule.SetNoiseQuality(noise::QUALITY_BEST);

    utils::NoiseMap heightMap;
    utils::NoiseMapBuilderSphere heightMapBuilder;
    heightMapBuilder.SetSourceModule (myModule);
    heightMapBuilder.SetDestNoiseMap (heightMap);
    heightMapBuilder.SetDestSize (512, 256);
    heightMapBuilder.SetBounds (-90.0, 90.0, -180.0, 180.0);
    heightMapBuilder.Build ();

    utils::RendererImage renderer;
    utils::Image image;
    renderer.SetSourceNoiseMap (heightMap);
    renderer.SetDestImage (image);
    renderer.ClearGradient ();
    renderer.AddGradientPoint (-1.0000, utils::Color (  0,   0, 128, 255)); // deeps
    renderer.AddGradientPoint (-0.2500, utils::Color (  0,   0, 255, 255)); // shallow
    renderer.AddGradientPoint ( 0.0000, utils::Color (  0, 128, 255, 255)); // shore
    renderer.AddGradientPoint ( 0.0625, utils::Color (240, 240,  64, 255)); // sand
    renderer.AddGradientPoint ( 0.1250, utils::Color ( 32, 160,   0, 255)); // grass
    renderer.AddGradientPoint ( 0.3750, utils::Color (224, 224,   0, 255)); // dirt
    renderer.AddGradientPoint ( 0.7500, utils::Color (128, 128, 128, 255)); // rock
    renderer.AddGradientPoint ( 1.0000, utils::Color (255, 255, 255, 255)); // snow
    renderer.EnableLight ();
    renderer.SetLightContrast (3.0);
    renderer.SetLightBrightness (2.0);
    renderer.Render ();

    utils::WriterBMP writer;
    writer.SetSourceImage (image);
    writer.SetDestFilename ("tutorial.bmp");
    writer.WriteDestFile ();

    int i;
    std::cin >> i;

    return 0;
}
